#ifndef ALLTOALLBENCH_H
#define ALLTOALLBENCH_H

#include <stdio.h>
#include <stdlib.h>
#include "FFTEngine.h"
#include "Complex.h"
#include "CommLayer.h"

//2^14
//#define MAXN 16384
#define MAXN 1024

class AllToAllBench : public FFTEngine {

public:

	double *sendBuff;	
	double *recBuff;	
	

	/** Constructors **/
	AllToAllBench(int iNumPoints, CommLayer *iComm) : FFTEngine(iNumPoints,iComm) {


		sendBuff = (double *) malloc(sizeof(double)*numNodes*MAXN);
		recBuff = (double *) malloc(sizeof(double)*numNodes*MAXN);

		if (sendBuff == NULL || recBuff == NULL) {
			fprintf(stderr,"Malloc Failure\n");
		}


		
		for (long i=0; i < numNodes*MAXN; i++) { 
			sendBuff[i] = (double) i;
		}
		
	} 

	~AllToAllBench() {
		free(sendBuff);
		free(recBuff);
	}


	/** FFT Driver functions
		uses distributeData(arr,isScatter,isCyclic,isBitReversed) 
	**/
	virtual void distributeInitData(Complex *arr) { distributeData(arr,true,true,false); }
	virtual void aquireInitData() { distributeData(NULL,true,true,false); }
	
	virtual void acquireResultData(Complex *arr) { distributeData(arr,false,false,true); }
	virtual void distributeResultData() { distributeData(NULL,false,false,true); }

	virtual void executeFFT(); //computes the FFT in localData
	virtual void executeFFT(bool onlyComm);

private:
	
	virtual bool isLocal(int globalId) { return blocked_globalNode(globalId) == rank; }
	virtual int global2localId(int globalId) { return blocked_global2localId(globalId); }	
	virtual int globalNode(int globalId) { return blocked_globalNode(globalId); }	


};
#endif
